package com.sfac.config.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;

/**
 * @Author:唐琳的爹
 * @BelongsProject:hqyj_springboot
 * @BelongsPackage:com.sfac.config.shiro
 * @CreateTime:2022/8/31 10:20:08
 */
@Configuration
public class ShiroConfig {

    @Autowired
    private MyRealm myRealm;

    @Bean
    public DefaultWebSecurityManager securityManager(){
        // 管理realm
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm);
        return securityManager;
    }


    /**
     * anon：匿名访问，无需登录 ---- AnonymousFilter
     * authc：登录后才能访问 ---- FormAuthenticationFilter
     * user：登录过能访问 ---- UserFilter
     * logout：登出 ---- LogoutFilter
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        ShiroFilterFactoryBean filterFactoryBean = new ShiroFilterFactoryBean();
        // 注入安全管理器
        filterFactoryBean.setSecurityManager(securityManager());
        // 设置登录页面,登录成功页面
        filterFactoryBean.setLoginUrl("/account/login");
        filterFactoryBean.setSuccessUrl("/test/thymeleaf");

        // 设置其余地址的访问规则
        LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
        // 登录注册
        filterMap.put("/account/login","anon");
        filterMap.put("/user/login","anon");
        filterMap.put("/account/register","anon");
        filterMap.put("/user/register","anon");
        // 静态资源
        filterMap.put("/static/**","anon");
        // 注意这里的static不是指项目中的static而是访问路径的static映射路径
        filterMap.put("/css/**","anon");
        filterMap.put("/image/**","anon");
        filterMap.put("/js/**","anon");
        filterMap.put("/vendors/**","anon");
        // 测试模块
        filterMap.put("/test/**","anon");
        // api
        filterMap.put("/user/**","anon");

        filterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return filterFactoryBean;
    }


    /**
     * - 注册shiro方言，让 thymeleaf 支持 shiro 标签
     */
    @Bean
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }

    /**
     * DefaultAdvisorAutoProxyCreator, Advisor 代理类生成器
     */
    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }

    /**
     * - 创建 AuthorizationAttributeSourceAdvisor，扫描 Shiro 注解
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }


}
